<template>
    <div ref="counterRef" class="counter" :style="{ height: fontSize, lineHeight: fontSize, fontSize }">
        <template v-for="(str, index) in numbers" :key="index">
            <Transition name="counter">
                <div ref="numbersRef" class="counter-number">
                    <template v-if="isSymbol(str)">{{ str }}</template>
                    <template v-else>
                        <div v-for="n in 10" :key="n" class="counter-number-item">{{ n - 1 }}</div>
                    </template>
                </div>
            </Transition>
        </template>
    </div>
</template>

<script setup>
import { computed, onMounted, reactive, ref, watchEffect } from "vue";

import addCommas from "@/utils/addCommas";
import waiting from "@/utils/waiting";

const props = defineProps({
    value: {
        type: [Number, String],
        required: true,
    },
    commas: {
        type: Boolean,
        default: false,
    },
    fontSize: {
        type: [Number, String],
        default: "14px",
    },
});

const counterRef = ref(null);
const numbersRef = ref(null);

const numbers = computed(() => (props.commas ? addCommas(props.value) : `${props.value}`));
const fontSizeNumber = computed(() => parseInt(props.fontSize));
const fontSize = computed(() => `${fontSizeNumber.value}px`);

const isSymbol = (str) => /^\.|,$/.test(str);

watchEffect(async () => {
    if (!numbersRef.value || !numbers.value) return;

    await waiting(0);
    numbersRef.value.forEach(async (item, index) => {
        if (isSymbol(numbers.value[index])) {
            item.style.transitionDuration = "0s";
            item.style.transform = "";
        } else {
            const number = Number(numbers.value[index]);

            item.style.transitionDuration = `${0.3 * (number + 1)}s`;
            item.style.transform = `translateY(-${fontSizeNumber.value * number}px)`;
        }
    });
});
</script>

<style lang="scss" scoped>
.counter {
    display: inline-flex;
    align-items: center;
    overflow: hidden;
    .counter-number {
        display: flex;
        flex-direction: column;
        height: 100%;
        transform: translateY(0);
        transition: transform 0.3s ease-in-out 0s;
    }
}
</style>
